<script setup lang="ts">
//文章模版
import {
  ref,
  watch,
  reactive,
  computed,
  provide,
  inject,
  Ref,
  watchEffect,
} from "vue";
import { useRoute, useRouter } from "vue-router";
import SoftwareData from "@/data/software/index";
import { goNotFound, shuffleArray } from "@/store/tool";
import SingleSon from "@/components/template/single_son.vue";

//准备路由
const route = useRoute();
const router = useRouter();

//拿到当前路由path
const RouterPath = inject("RouterPath") as Ref<{
  pagename: string;
  screen: string;
}>;

//拿到当前系统筛选的值
const screenSystem = inject("screenSystem") as Ref<
  "All" | "Win" | "Mac" | "Linux" | "Web"
>;

//获取默认系统值
const defaultSystem = computed(() => {
  //从URL中拿到系统值
  return route.query.system;
});

//分享链接时用，监听链接 若有系统值则传入值
watch(
  () => defaultSystem.value,
  (newId) => {
    if (defaultSystem.value) {
      screenSystem.value = newId!.toString() as
        | "All"
        | "Win"
        | "Mac"
        | "Linux"
        | "Web";
    }
  }
);

//找出符合当前路由的值
const result = computed(() => {
  const data = SoftwareData.find(
    (item) => item.path === RouterPath.value.pagename
  );
  return data;
});

//传给子组件
const screenData = reactive({
  //点击传值 - 筛选用
  setScreenValue(item: string) {
    if (item !== "all") {
      //修改路由
      router.push({
        name: "screen",
        params: { screen: item },
      });
    } else {
      //点击全部，回到当前二级筛选的父级路由
      const url = RouterPath.value.pagename;
      // 命名的路由，并加上参数，让路由建立 url
      router.push({ name: "cat", params: { pagename: url } });
    }
  },
});

provide("screenData", screenData);

//存储筛选用表头
const headScreenData = ref([{ type: "", path: "" }]);

// 使用 map 方法将每个对象转换为包含 type 和 path 属性的新对象
watchEffect(() => {
  //拿到表头需要的数组对象
  const newArray = result.value?.data.map((obj) => {
    return {
      type: obj.type, //名称
      path: obj.path, //路由
    };
  });

  if (newArray) {
    //首位添加“全部”筛选选项
    newArray.unshift({ type: "全部", path: "all" });
    //传值
    headScreenData.value = newArray;
  } else {
    //没有找到表头数据，则跳转404
    goNotFound();
  }
});

//获取所有二级路由，组成数组
// 初始化一个空数组来存储所有的 path 值
let sitePathArray: string[] = [];

// 遍历 SoftwareData 数组中的每个对象
SoftwareData.forEach((obj) => {
  // 遍历当前对象的 data 数组
  obj.data.forEach((item) => {
    // 将每个 item 的 path 值加入到 sitePathArray 数组中
    sitePathArray.push(item.path);
  });
});

// 计算属性：返回按二级菜单筛选和系统筛选后的数据列表
const filteredData = computed(() => {
  // 获取二级筛选菜单路径
  const pathScreen = RouterPath.value.screen;

  // 检查是否存在二级筛选菜单且路径在数组中
  const screenDataType =
    pathScreen && sitePathArray.includes(pathScreen) && result.value;

  if (screenDataType) {
    // 获取二级筛选后的数据
    const screenData = result.value.data.find((obj) => obj.path === pathScreen);

    // 如果不存在二级筛选后的数据，返回 undefined
    if (!screenData) {
      return undefined;
    }

    // 根据系统类型进行筛选
    let systemScreenData;
    if (screenSystem.value === "All") {
      // 如果筛选的是 "All"，则直接返回数据
      systemScreenData = screenData.data;
    } else {
      // 根据系统类型进行筛选
      systemScreenData = screenData.data.filter((item) =>
        item.system
          ? item.system.includes(screenSystem.value)
          : screenSystem.value
      );
    }

    // 如果没有筛选出数据，返回 undefined
    if (!systemScreenData) {
      return undefined;
    }

    // 构造返回的数据对象
    return {
      data: systemScreenData,
      type: screenData.type,
      path: screenData.path,
      describe: screenData.describe,
    };
  }

  // 如果不存在二级筛选，获取所有当前父分类下的值
  const newArray = result.value?.data.flatMap((obj) => obj.data);

  // 根据系统类型进行筛选
  let systemScreenData;
  if (screenSystem.value === "All") {
    systemScreenData = newArray;
  } else {
    // 筛选出符合系统类型的数据
    systemScreenData = newArray?.filter((item) =>
      item.system
        ? item.system.includes(screenSystem.value)
        : screenSystem.value
    );
  }

  // 如果没有筛选出数据，返回 undefined
  if (!systemScreenData) {
    return undefined;
  }

  // 使用洗牌算法随机化数组
  //仅在一级菜单下，仅进行系统筛选时，进行洗牌
  const shuffData = shuffleArray(systemScreenData);

  // 构造返回的数据对象
  return {
    data: shuffData,
    type: "全部",
    path: "all",
  };
});

//监听，跳转至404页面
watchEffect(() => {
  //拿到当前的path
  const path = RouterPath.value.screen;

  //确定页面在二级菜单并且不在二级菜单数组中
  const type = path && !sitePathArray.includes(path);

  //或者，监听headScreenData，没有值也跳转
  if (type || !filteredData) {
    //跳转 404 页面
    goNotFound();
  }
});
</script>
<template>
  <!--展示引导列表-->
  <SingleSon
    :screenArr="headScreenData"
    :filteredData="filteredData"
    v-if="filteredData"
  />
</template>
